/**
 * @file spi.c
 * @author leijiapeng (email:leijiapeng123@163.com)
 * @brief  软件SPI
 * @version 0.1
 * @date 2025-09-18
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "spi.h"
#include "stm32f1xx_hal.h"

static void MySPI_WriteCS(uint8_t val) { HAL_GPIO_WritePin(MySPI_CS_GPIO_PORT, MySPI_CS_GPIO_PIN, (GPIO_PinState)val); }

static void MySPI_WriteSCK(uint8_t val) { HAL_GPIO_WritePin(MySPI_SCK_GPIO_PORT, MySPI_SCK_GPIO_PIN, (GPIO_PinState)val); }

static void MySPI_WriteMOSI(uint8_t val) { HAL_GPIO_WritePin(MySPI_MOSI_GPIO_PORT, MySPI_MOSI_GPIO_PIN, (GPIO_PinState)val); }

static uint8_t MySPI_ReadMISO(void) { return HAL_GPIO_ReadPin(MySPI_MISO_GPIO_PORT, MySPI_MISO_GPIO_PIN); }

void MySPI_Init(void)
{
    MySPI_WriteCS(1);  // 片选拉高,不选中
    MySPI_WriteSCK(0); // 时钟空闲时低电平
}

void MySPI_Start(void)
{
    MySPI_WriteCS(0); // 片选拉低,选中
}

void MySPI_Stop(void)
{
    MySPI_WriteCS(1); // 片选拉高,不选中
}

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
    uint8_t i, ByteReceive = 0x00;

    for (i = 0; i < 8; i++) // 循环8次，依次交换每一位数据
    {
        MySPI_WriteMOSI(!!(ByteSend & (0x80 >> i))); // 两次逻辑非保证非0数变成1，0变成0
        MySPI_WriteSCK(1);                           // 拉高SCK，指示从机采样数据
        if (MySPI_ReadMISO() == 1)
        {
            ByteReceive |= (0x80 >> i); // 读取MISO数据，并存储到Byte变量
        }
        MySPI_WriteSCK(0); // 拉低SCK，指示从机切换数据
    }

    return ByteReceive; // 返回接收到的一个字节数据
}
